/*
 *
 * Copyright(c) 2010 Safelayer Secure Communications
 *
 * This is open source software, placed under the terms of the
 * GNU GENERAL PUBLIC LICENSE Version 3.
 * Please see: http://www.gnu.org/licenses/gpl-3.0.txt
 * 
 * Permission to use, copy, modify, and distribute this software
 * for any purpose and without fee is hereby granted, provided
 * that the above copyright notices appear in all copies and that
 * both the copyright notice and this permission notice appear in
 * supporting documentation.
 * 
 */
package com.neuralnoise.foaf.core;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

/**
 * Models a FOAF OnlineAccount. The <code>OnlineAccount</code> class represents the provision of
 * some form of online service, by some party (indicated indirectly via an accountServiceHomepage to
 * some {@link Agent}. The account property of the agent is used to indicate accounts that are
 * associated with the agent.
 * <p>
 * For more info see FOAF Vocabulary Specification
 * 
 * @author victor <swtp@safelayer.com>
 * 
 */
public class OnlineAccount extends Thing {

	private String accountName;

	private Set<Document> accountServiceHomepageSet = new LinkedHashSet<Document>();

	public OnlineAccount() {
		super(null);
	}

	public OnlineAccount(String uri) {
		super(uri);
	}

	/**
	 * @return the accountName
	 */
	public String getAccountName() {
		return accountName;
	}

	/**
	 * @param accountName The accountName to set.
	 */
	public void setAccountName(String accountName) {
		this.accountName = accountName;
	}

	/**
	 * Returns all accountServiceHomepages.
	 * 
	 * @return Returns all accountServiceHomepages.
	 */
	public List<Document> getAllAccountServiceHomepages() {
		return new ArrayList<Document>(accountServiceHomepageSet);
	}

	/**
	 * Adds the specified <code>accountServiceHomepage</code> to this {@link OnlineAccount} if it is
	 * not already present.
	 * 
	 * @param accountServiceHomepage The <code>accountServiceHomepage</code> to be added to this
	 *            <code>OnlineAccount</code> .
	 * @return <tt>true</tt> if the <code>OnlineAccount</code>. did not already contain the
	 *         specified <code>accountServiceHomepage</code>
	 */
	public boolean addAccountServiceHomepage(Document accountServiceHomepage) {
		return accountServiceHomepageSet.add(accountServiceHomepage);
	}

	/**
	 * Removes the specified <code>accountServiceHomepage</code> from this {@link OnlineAccount}, if
	 * it is present. Returns <tt>true</tt> if this <code>OnlineAccount</code> contained the
	 * specified <code>accountServiceHomepage</code> (or equivalently, if this
	 * <code>OnlineAccount</code> changed as a result of the call).
	 * 
	 * @param accountServiceHomepage The <code>accountServiceHomepage</code> to be removed from this
	 *            <code>OnlineAccount</code>.
	 * @return <tt>true</tt> if this <code>OnlineAccount</code> contained the specified
	 *         <code>accountServiceHomepage</code>
	 */
	public boolean removeAccountServiceHomepage(Document accountServiceHomepage) {
		return accountServiceHomepageSet.remove(accountServiceHomepage);
	}

	/**
	 * Removes all of the accountServiceHomepages from this {@link OnlineAccount}. The
	 * accountServiceHomepages from <code>OnlineAccount</code> will be empty after this call
	 * returns.
	 */
	public void clearAccountServiceHomepages() {
		accountServiceHomepageSet.clear();
	}

	/**
	 * Returns <tt>true</tt> if this {@link OnlineAccount} contains the specified
	 * <code>accountServiceHomepage</code>
	 * 
	 * @param accountServiceHomepage The <code>accountServiceHomepage</code> whose presence in this
	 *            <code>OnlineAccount</code> is to be tested.
	 * @return <tt>true</tt> if this <code>OnlineAccount</code> contains the specified
	 *         <code>accountServiceHomepage</code>
	 */
	public boolean containsAccountServiceHomepage(Document accountServiceHomepage) {
		return accountServiceHomepageSet.contains(accountServiceHomepage);
	}

	/**
	 * Determines hashCode value base on the <code>accountName</code>. If accountName is <tt>null</tt>
	 * then call {@link Thing#hashCode()}.
	 */
	@Override
	public int hashCode() {
		if (accountName != null) {
			final int prime = 31;
			int result = super.hashCode();
			result = prime * result + ((accountName == null) ? 0 : accountName.hashCode());
			return result;
		}
		else {
			// call Thing hashCode
			return super.hashCode();
		}
	}

	/**
	 * Determines whether two OnlineAccounts are equal, their accountNames are equal. If
	 * accountName is <tt>null</tt> then call {@link Thing#equals(Object)}.
	 * 
	 * @param obj The object to be compared.
	 * @return true if and only if both objects are equal.
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!super.equals(obj))
			return false;
		if (getClass() != obj.getClass())
			return false;
		OnlineAccount other = (OnlineAccount) obj;
		if (accountName == null) {
			// call Thing equals
			return super.equals(obj);
		}
		else if (!accountName.equals(other.accountName))
			return false;
		return true;
	}
}
